#!/bin/bash

# Copyleft 2006 - 2007 Tiberiu Turbureanu

declare -rx SCRIPT=${0##*/}
# numele scriptului

declare IN_DIR="."
# directorul de input
declare OUT_DIR="."
# directorul de output

declare FILE
declare SUB_OUT_DIR
declare -i ERR_ARCH=0
# numarul de arhive care dau erori la compilarea sursei tema.c
declare -i WAR_ARCH=0
# numarul de arhive care dau amenintari la compilarea sursei tema.c
declare -i COUNT_ARCH=0
# numarul de arhive procesate

function create_dir
{
	SUB_OUT_DIR="${FILE%%.*}";
	# SUB_OUT_DIR retine numele fisierului, fara extensie
		
	SUB_OUT_DIR=${SUB_OUT_DIR/"_"/" "};
	# se inlocuieste prima sublinie din SUB_OUT_DIR cu ' '

	SUB_OUT_DIR=${SUB_OUT_DIR/"_"/" ("};
	# se inlocuieste a doua sublinie (cea de dinaintea grupei) din SUB_OUT_DIR cu ' ' si '('

	SUB_OUT_DIR="$SUB_OUT_DIR)";
	# in final, se inchide paranteza dupa grupa si se salveaza stringul in SUB_OUT_DIR

	if test ! -d "$OUT_DIR/$SUB_OUT_DIR"; then
		 mkdir "$OUT_DIR/$SUB_OUT_DIR";
	fi
	# se creeaza sudirectorul in directorul de output
}
readonly -f create_dir
declare -t create_dir

function unarch_status
{
	echo "Arhiva $FILE:"

	if [ -e "$OUT_DIR/$SUB_OUT_DIR"/tema.c -a -e "$OUT_DIR/$SUB_OUT_DIR"/readme.txt ]; then
		echo "extrasa OK";
	fi

	if test ! -e "$OUT_DIR/$SUB_OUT_DIR"/tema.c; then
		echo "nu a fost gasit fisierul tema.c";
	fi
	
	if test ! -e "$OUT_DIR/$SUB_OUT_DIR"/readme.txt; then
		echo "nu a fost gasit fisierul readme.txt";
	fi
	# se verifica daca arhiva contine ambele fisiere (readme.txt si tema.c),
	# verificandu-se de fapt daca, in urma dezarhivarii, exista in subdirector cele doua fisiere;
}
readonly -f unarch_status
declare -t unarch_status

function is_substring
{
	declare AUX="${2#*$1}"
	
	if [ ${#AUX} -ne ${#2} ]; then return 0;
	else return 1;
	fi
	# se testeaza daca primul parametru este subsir al celui de-al doilea parametru
}
readonly -f is_substring
declare -t is_substring

function compile
{
	declare -i ERR_COUNT=0
	declare -i WAR_COUNT=0
	declare LINE
	declare ERR_STR="liniile"
	declare WAR_STR="liniile"
	declare AUX
	
	gcc "$OUT_DIR/$SUB_OUT_DIR/tema.c" -o "$OUT_DIR/$SUB_OUT_DIR/tema" -O2 -Wall -lm -pedantic 2> "$OUT_DIR/$SUB_OUT_DIR/rez.txt"
	# se compileaza sursa tema.c, iar outputul gcc este copiat in fisierul rez.txt
	while read LINE;
	do
		is_substring "warning" "$LINE";
		if [ $? -eq 0 ]; then  
			WAR_COUNT+=1;
			AUX=`echo "$LINE" | cut -f 2 -d ':'`;
			is_substring "$AUX" "$WAR_STR";
			if [ $? -eq 1 ]; then
				WAR_STR="$WAR_STR $AUX";
			fi
		else
			is_substring "error" "$LINE";
			if [ $? -eq 0 ]; then
				ERR_COUNT+=1;
				AUX=`echo "$LINE" | cut -f 2 -d ':'`;
				is_substring "$AUX" "$ERR_STR";
				if [ $? -eq 1 ]; then
					ERR_STR="$ERR_STR $AUX";
				fi
			fi
		fi
		# se contorizeaza fiecare amenintare si eroare din outputul gcc (retinut in rez.txt), 
		# inregistrandu-se liniile pe care au fost intalnite,
		# in masura in care nu au fost deja inregistrate, in stringurile WAR_STR, respectiv ERR_STR
	done <"$OUT_DIR/$SUB_OUT_DIR/rez.txt"

	if [ $ERR_COUNT -eq 0 ]; then 
		printf "Nici o eroare\n\n" >"$OUT_DIR/$SUB_OUT_DIR/rezultate.txt"
	else
		ERR_ARCH+=1
		printf "%d erori: %s\n\n" $ERR_COUNT "$ERR_STR" >"$OUT_DIR/$SUB_OUT_DIR/rezultate.txt"
	fi

	if [ $WAR_COUNT -eq 0 ]; then
		printf "Nici un warning\n\n" >>"$OUT_DIR/$SUB_OUT_DIR/rezultate.txt"
	else
		WAR_ARCH+=1
		printf "%d amenintari: %s\n\n" $WAR_COUNT "$WAR_STR" >>"$OUT_DIR/$SUB_OUT_DIR/rezultate.txt"
	fi
	# se salveaza in fisierul rezultate.txt numarul de erori si de amenintari, impreuna cu liniile pe care au fost intalnite

	printf "Output:\n\n\n" >>"$OUT_DIR/$SUB_OUT_DIR/rezultate.txt"
	printf "gcc %s/tema.c -o %s/tema -O2 -Wall -lm -pedantic\n\n" "$OUT_DIR/$SUB_OUT_DIR" "$OUT_DIR/$SUB_OUT_DIR"  >>"$OUT_DIR/$SUB_OUT_DIR/rezultate.txt"
	# se salveaza comanda de compilare in fisierul rezultate.txt

	cat "$OUT_DIR/$SUB_OUT_DIR/rez.txt" >>"$OUT_DIR/$SUB_OUT_DIR/rezultate.txt"
	# se copiaza masa outputului gcc din fisierul temporar rez.txt, la sfarsitul fisierului rezultate.txt

	rm "$OUT_DIR/$SUB_OUT_DIR/rez.txt"
	# se sterge fisierul temporar rez.txt

	COUNT_ARCH+=1
}
readonly -f compile
declare -t compile

# se interpreteaza parametrii comenzii:
#
while [ $# -gt 0 ]; do
	case "$1" in
	-h | --help)
		printf "%s\n" "comanda are formatul: $SCRIPT [-h | --help] [-i | --input] director_input [-o | --ouput] director_output [-a | --archives] arhive"
		;;
	-i | --input)
		shift
		if [ $# -eq 0 ]; then
			printf "$SCRIPT:$LINENO: se astepta directorul de input" >&2
			exit 192
		fi

		IN_DIR="$1"
		;;
	-o | --output)
		shift
		if [ $# -eq 0 ]; then
			printf "$SCRIPT:$LINENO: se astepta directorul de output" >&2
			exit 192
		fi
			
		OUT_DIR="$1"
		;;
	-a | --archives)
		shift
		break
		;;
	-*)
		printf "$SCRIPT:$LINENO: nu se cunoaste un astfel tip de parametru" >&2
		exit 192
		;;
	*)
		printf "$SCRIPT:$LINENO: nu se cunoaste un astfel tip de parametru sau parametru" >&2
		exit 192
		;;
	esac
	shift
done

if test ! -d "$OUT_DIR"; then 
	printf "%s\n" "$SCRIPT:$LINENO: nu exista directorul de destinatie specificat"
	exit 1;
fi
# se verifica daca exista directorul de output

declare -i okay

for FILE in "$IN_DIR"/*;
# se retine in FILE numele fiecarui fisier din directorul de input
do
	if test -f "$FILE"; then

		okay=0
			
		FILE="${FILE##*/}";
		# FILE retine acum doar numele fisierului, fara intreaga cale

		if [ $# -ne 0 ]; then
			is_substring "$FILE" "$*"
			okay=$?
		fi
		# in cazul in care sunt specificate ca parametrii de comanda arhivele care se vor a fi procesate,
		# se verifica daca FILE este una dintre acestea

		if [ $okay -eq 0 ]; then
		# in caz afirmativ, se procedeaza la recunoasterea tipului arhivei
			case "${FILE#*.}" in
 			tgz | tar.gz)
				create_dir
				tar -xzf "$IN_DIR/$FILE" -C "$OUT_DIR/$SUB_OUT_DIR" tema.c readme.txt 2>/dev/null
				unarch_status
				compile
				echo
				;;
			tbz | tar.bz2)
				create_dir
				tar -xjf "$IN_DIR/$FILE" -C "$OUT_DIR/$SUB_OUT_DIR" tema.c readme.txt 2>/dev/null
				unarch_status
				compile
				echo
				;;
			tar)
				create_dir
				tar -xf "$IN_DIR/$FILE" -C "$OUT_DIR/$SUB_OUT_DIR" tema.c readme.txt 2>/dev/null
				unarch_status
				compile
				echo
				;;
			zip)
				create_dir
				unzip -o "$IN_DIR/$FILE" -d "$OUT_DIR/$SUB_OUT_DIR" tema.c readme.txt >/dev/null
				unarch_status
				compile
				echo
				;;
			esac
			# pentru fiecare tip uzual de arhiva recunoscut:
			#
			# se creeaza subdirectorul cu numele, prenumele si grupa subiectului, in directorul de output
			# se dezarhiveaza arhiva in subdirectorul creat
			# se afiseaza constatarile in urma dezarhivarii
			# se compileaza sursa tema.c, daca aceasta exista
		fi
	fi
done

echo $COUNT_ARCH arhive au fost procesate
echo $ERR_ARCH arhive au dat erori
echo $WAR_ARCH arhive au dat amenintari
# se afiseaza statistica evaluarii

exit 0
